package com.mainbo.androidframework.persistence.db;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;


import com.mainbo.androidframework.persistence.db.dao.BaseDao;

import java.lang.reflect.Constructor;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 *
 * <b>create time</b> 2015/5/26
 *
 * @author weilh
 */
public abstract class BaseDbHelper extends SQLiteOpenHelper {
    /**
     * 必须在子类构造函数中创建
     */
    private SQLiteDatabase mDb;
    private Map<String, BaseDao> daoMap = Collections.synchronizedMap(new HashMap<String, BaseDao>());

    public BaseDbHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
        mDb = getWritableDatabase();
    }

    public void beginTransaction() throws DbException{
        try {
            if (mDb != null) {
                mDb.beginTransaction();
            }
        } catch (Exception e) {
            throw new DbException(e);
        }
    }

    public void endTransaction() throws DbException{
        try {
            if (mDb != null) {
                mDb.endTransaction();
            }
        } catch (Exception e) {
            throw new DbException(e);
        }
    }

    public void setTransactionSuccessful() throws DbException{
        try {
            if (mDb != null && mDb.isOpen()) {
                mDb.setTransactionSuccessful();
            }
        } catch (Exception e) {
            throw new DbException(e);
        }
    }

    @Override
    public synchronized void close() {
        try {
            endTransaction();
        } catch (DbException e) {
            e.printStackTrace();
        }
        super.close();
    }

    /**
     * 获取数据库表的操作对象
     *
     * @param tClass 对象Class
     * @param <T>    类型
     * @return 表操作对象
     */
    protected synchronized <T extends BaseDao> T getBaseDao(Class<T> tClass) {
        BaseDao dao = daoMap.get(tClass.getName());
        if (dao == null) {
            try {
                Constructor<T> constructor = tClass.getConstructor();
                dao = constructor.newInstance();
                if (mDb == null) {
                    mDb = getWritableDatabase();
                }
                dao.setDb(mDb);
                daoMap.put(tClass.getName(), dao);//存入dao字典中，根据类名索引
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (dao == null) return null;
        return (T) dao;
    }
}
